import serial
from tkinter import *
from tkinter import messagebox
import serial.tools.list_ports
import time
import pandas as pd
import datetime
import os
import openpyxl
fileName = 'setrecord.xlsx'
if not os.path.isfile(fileName):
    dfData = {'time': []}
    for i in range(22,52):
        dfData['通道'+str(i)+'状态']=[]
    df = pd.DataFrame(dfData)  # 创建DataFrame
    df.to_excel(fileName, index=False)  # 存表，去除原始索引列（0,1,2...）
workbook = openpyxl.load_workbook(fileName)
sheets_name = workbook.sheetnames  # 获取工作薄的所有的sheet名称
worksheet = workbook[sheets_name[0]]  # 获取工作薄中的第一个sheet

class Application(Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master=master
        self.ser = serial.Serial(port=None, baudrate=9600)
        self.channelmachine = pd.read_excel(io="按钮设备映射关系.xlsx").to_dict(orient ='records')
        self.channelnumber=len(self.channelmachine)
        self.channelstate = {}
        self.BUttonlist={}
        self.createWidget()
        self.openCOM()
        self.pack()
    def createWidget(self):
        Label(self,text="串口状态:",width=8,height=2).grid(column=0,row=0,padx=10,pady=10)
        self.SelectCOM=StringVar()
        self.SelectCOM.set("")
        Label(self,textvariable= self.SelectCOM,width=8,height=2,bg="white").grid(column=1,row=0,padx=10,pady=10)
        self.SelectCOMState = StringVar()
        self.SelectCOMState.set("")
        Label(self, textvariable=self.SelectCOMState,width=8,height=2,bg="white").grid(column=2, row=0,padx=10,pady=10)
        Button(self, text="刷新", command=self.openCOM, width=8, height=2).grid(column=3, row=0,padx=10,pady=10)

        for i in range(0,self.channelnumber):
            self.channelstate[str(i)] = IntVar()
            self.channelstate[str(i)].set(0)
            self.BUttonlist[str(i)]=Button(self, text=self.channelmachine[i]['设备'], command=lambda arg=i: self.changechannel(arg),width=8,height=2,bg="gray")
            self.BUttonlist[str(i)].grid(column=i % 6, row=2 + int(i / 6),padx=10,pady=10)
        Button(self,text="保存",command=self.saveseting,width=8, height=2).grid(column=0, row=3 + self.channelnumber // 6,padx=10,pady=10)
        Button(self, text="载入", command=self.reload, width=8, height=2).grid(column=1,
                                                                                   row=3 + self.channelnumber // 6,
                                                                                   padx=10, pady=10)
        comment=Text(self,height=4, width=10)
        comment.insert('end', "通道电压变更间隔>=30ms,载入有1.5s延迟。")
        comment.grid(column=2, row=3 + self.channelnumber // 6)
    def openCOM(self):
        plist = list(serial.tools.list_ports.comports())
        for comport in plist:
            if "Arduino Mega 2560" in list(comport)[1]:
                target_port=list(comport)[0]
                self.ser.port = target_port
                if not self.ser.isOpen():
                    self.ser.open()
                self.SelectCOM.set(target_port)
                self.SelectCOMState.set("已开启")
                break
    def changechannel(self,channelindex):
        if self.ser.port!=None and self.ser.isOpen():
            if self.channelstate[str(channelindex)].get()==0:
                self.setchannelhigh(channelindex)
            else:
                self.setchannellow(channelindex)
            self.saveseting()
        else:
            messagebox.showinfo("错误信息","串口未打开")
    def saveseting(self):
        timevoltageinfo = []
        timevoltageinfo.append(datetime.datetime.now())
        for channelindex in range(0,self.channelnumber):
            timevoltageinfo.append(self.channelstate[str(channelindex)].get())
        worksheet.append(timevoltageinfo)
        workbook.save(fileName)
    def reload(self):
        if self.ser.port != None and self.ser.isOpen():
            if worksheet.max_row==1:
                messagebox.showinfo("错误信息", "文件setrecord.xlsx中没有过往电压设置信息")
            else:
                timevoltageinfo=worksheet[worksheet.max_row-1]
                for channelindex in range(0, self.channelnumber):
                    if timevoltageinfo[channelindex+1].value==1:
                        self.setchannelhigh(channelindex)
                    elif timevoltageinfo[channelindex+1].value==0:
                        self.setchannellow(channelindex)
                    else:
                        messagebox.showinfo("错误信息", "检测到非法电压设置信息，请检查setrecord.xlsx")
                        break
                    time.sleep(0.05)
        else:
            messagebox.showinfo("错误信息", "串口未打开")
    def setchannelhigh(self,channelindex):
        commessage = str(self.channelmachine[channelindex]['通道']) + "1"
        self.ser.write(commessage.encode('UTF-8'))
        self.channelstate[str(channelindex)].set(1)
        self.BUttonlist[str(channelindex)].configure(bg="green")
    def setchannellow(self,channelindex):
        commessage = str(self.channelmachine[channelindex]['通道']) + "0"
        self.ser.write(commessage.encode('UTF-8'))
        self.channelstate[str(channelindex)].set(0)
        self.BUttonlist[str(channelindex)].configure(bg="gray")
root=Tk()
root.title("Arduino数字输出控制系统")
root.geometry("600x500+100+200")
ZW_DC_GUIapp=Application(master=root)
root.mainloop()



